package com.zhl.actor;

import akka.actor.ActorRef;
import akka.actor.ActorSelection;
import akka.actor.Props;
import akka.actor.UntypedActor;
import akka.util.Timeout;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.concurrent.duration.Duration;

import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Created by Administrator on 2018/12/29.
 * 主要添加了日志
 */
public abstract class BaseActor extends UntypedActor {

    protected static Logger log = LoggerFactory.getLogger(BaseActor.class);
    public static Timeout timeout = new Timeout(Duration.create(5L, "seconds"));
    private final int MAX_ACTORS_NUM = 1000000;
    protected String actorKey = "";
    protected String pathStr = "";
    public static ConcurrentMap<String, String> allActors = new ConcurrentHashMap();

    public BaseActor() {
    }

    public void tell(String key, Object msg) throws Exception {
        this.tell(key, msg, (Class)null, new Object[0]);
    }

    public void tell(String key, Object msg, Class clazz, Object... objects) throws Exception {
        synchronized(key) {
            String trueKey;
            if(allActors.containsKey(key)) {
                trueKey = (String)allActors.get(key);
                log.info("{}选择子actor的{}路径为{}", new Object[]{this.actorKey, key, trueKey});
                ActorSelection actorSelection = this.context().actorSelection(trueKey);
                actorSelection.tell(msg, this.self());
            } else if(clazz != null) {
                if(allActors.size() > 1000000) {
                    throw new Exception("创建的Actor超过1000000,不给创建！");
                }

                trueKey = UUID.randomUUID().toString();
                ActorRef actor = this.context().actorOf(Props.create(clazz, objects), trueKey);
                log.info("新创建的{}actor路径为{}", trueKey, actor.path());
                actor.tell(msg, this.self());
            }

        }
    }

    public void preStart() throws Exception {
        if(StringUtils.isEmpty(this.actorKey)) {
            throw new Exception("没有设置ActorKey,不可以使用");
        } else {
            this.pathStr = this.self().path().toString();
            log.info("Actor{}启动{}", this.actorKey, this.pathStr);
            allActors.put(this.actorKey, this.pathStr);
            super.preStart();
        }
    }

    public void postStop() throws Exception {
        log.info("Actor{}停止{}", this.actorKey, this.pathStr);
        allActors.remove(this.actorKey);
        super.postStop();
    }
}
